﻿<template>
  <div class="formplane">
    <div class="fromitem">
      <div class="field-label" style="width:80px">触发字段</div>
      <div class="field-input">
        <el-select
          v-model="relationfield"
          size="small"
          placeholder="请选择触发的事件"
          :disabled="isedit"
          @change="relationfieldchange"
        >
          <el-option
            v-for="item in eventlist"
            :key="item.value"
            :label="item.title"
            :value="item.value"
          >
            <span
              :class="item.eventtype === 1 ? 'eventclass' : 'fieldclass'"
            ></span>
            {{ item.title }}
          </el-option>
        </el-select>
      </div>
      <div class="explain">
        <span>说明：</span>（<span class="fieldclass"></span
        >为字段，当字段值发生改变时触发调用自定义运算逻辑。<span
          class="eventclass"
        ></span
        >为事件,触发勾选的事件，将会触发自定义运算逻辑。）
        <!-- <el-checkbox-group v-model="relationfield">
          <el-checkbox :label="'loaddataafter'">数据加载后事件</el-checkbox>
          <el-checkbox :label="'beforesubmit'">提交前事件</el-checkbox>
          <el-checkbox v-for="item in fromVariableList" :label="item.value" :key="item.value" class="fieldcolor">{{item.title}}</el-checkbox>
        </el-checkbox-group> -->
      </div>
    </div>
    <div class="fromitem">
      <div class="field-label">运算逻辑</div>
      <div
        class="field-logic"
        ref="childlogic"
        contenteditable="true"
        @blur="logicblur"
        @click="logicblur"
        v-html="jscode"
        id="jscodechildlogic"
      ></div>
      <div class="explain">
        <span>说明：</span>（<span
          class="is-read"
          style="width: 12px;height: 12px;display: inline-block;"
        ></span
        >为只读变量<span
          class="is-fixed"
          style="width: 12px;height: 12px;display: inline-block;"
        ></span
        >为可写可读变量
        <span
          class="is-green"
          style="width: 12px;height: 12px;display: inline-block;"
        ></span
        >点击可以切换组数与变量类型，逻辑运算输入debugger;打断点，预览时可调试逻辑代码。）
      </div>
    </div>
    <div class="fromitem">
      <div class="fielditem1">
        <div class="field-label">可用变量(双击添加变量)</div>
        <div class="field-context">
          <el-collapse v-model="activeNames1">
            <el-collapse-item title="表单变量" name="1">
              <button
                class="fromfield"
                v-for="item in fromVariableList"
                :key="item.value"
                @click="createFromVariable(item)"
              >
                {{ item.title }}
              </button>
            </el-collapse-item>
            <el-collapse-item title="环境变量" name="2">
              <button
                class="fromfield"
                v-for="item in currentVariable"
                :key="item.value"
                @click="createCurrentVariable(item)"
              >
                {{ item.lable }}
              </button>
            </el-collapse-item>
            <el-collapse-item title="url参数或props变量" name="3">
            </el-collapse-item>
          </el-collapse>
        </div>
      </div>
      <div class="fielditem2">
        <div class="field-label">函数(双击添加函数，单机查看使用说明)</div>
        <div class="field-context">
          <el-collapse v-model="activeNames2">
            <el-collapse-item
              v-for="(item, key) in funconfig"
              :title="funanalysis[key]"
              :key="key"
              :name="key"
            >
              <button
                class="fromfield"
                v-for="(childitem, childkey) in item"
                :key="childkey"
                @click="createFunVariable(childitem)"
                @mouseover="clickFunVariable(funanalysis[childkey])"
              >
                {{ childkey }}
              </button>
            </el-collapse-item>
          </el-collapse>
        </div>
      </div>
      <div class="fielditem3">
        <div class="field-label">函数说明</div>
        <div class="field-context" v-html="explaincontext"></div>
      </div>
    </div>
    <div class="buttonitem">
      <el-button type="primary" @click="dialogsave">保存</el-button>
      <el-button @click="dialogclose">关闭</el-button>
    </div>
  </div>
</template>
<script>
import { findAllFromVariable } from '@/components/formdesign/findfrom.js'
import { funconfig, funanalysis } from '@/components/formdesign/formulafun.js'
export default {
  props: ['logicItem'],
  data() {
    return {
      currentVariable: [
        { value: '$user.userId', lable: '当前用户ID' },
        { value: '$user.userName', lable: '用户名称' },
        { value: '$user.name', lable: '用户真实名称' },
        { value: '$user.deptcode', lable: '部门编码' },
        { value: '$user.organcode', lable: '机构编码' },
        { value: '$user.organname', lable: '机构名称' },
        { value: '$user.deptname', lable: '部门名称' },
        { value: '$user.deptid', lable: '部门ID' },
        { value: '$user.organid', lable: '机构ID' },
        { value: '$user.phone', lable: '手机号码' },
        { value: '$user.avatar', lable: '形象图' }
      ],
      fromInfo: this.changeFromInfo(),
      fromVariableList: [],
      activeNames1: '',
      activeNames2: '',
      selection: undefined,
      relationfield: 'loaddataafter',
      jscode: '',
      logicname: '',
      eventlist: [
        { value: 'loaddatabefore', title: '数据加载之前事件', eventtype: 1 },
        { value: 'loaddataafter', title: '数据加载之后事件', eventtype: 1 },
        { value: 'beforesubmit', title: '提交前事件', eventtype: 1 }
      ],
      funconfig,
      funanalysis,
      explaincontext: '',
      isedit: false
    }
  },
  computed: {
    SetChangeFromInfo() {
      return this.changeFromInfo()
    }
  },
  methods: {
    pasteHtmlAtCaret(html) {
      const sel = this.selection
      let range
      if (
        sel !== undefined &&
        sel.anchorNode !== undefined &&
        sel.anchorNode.parentNode.className !== 'variable' &&
        (sel.anchorNode._prevClass === 'field-logic' ||
          sel.anchorNode.parentNode._prevClass === 'field-logic' ||
          sel.anchorNode.parentNode.parentNode._prevClass === 'field-logic')
      ) {
        if (sel.getRangeAt && sel.rangeCount) {
          range = sel.getRangeAt(0)
          range.deleteContents()
          const el = document.createElement('div')
          el.innerHTML = html
          const frag = document.createDocumentFragment()
          let node
          let lastNode
          while ((node = el.firstChild)) {
            lastNode = frag.appendChild(node)
          }
          range.insertNode(frag)
          if (lastNode) {
            range = range.cloneRange()
            range.setStartAfter(lastNode)
            range.collapse(true)
            sel.removeAllRanges()
            sel.addRange(range)
          }
        }
      } else {
        const jscodechildlogic = document.getElementById('jscodechildlogic')
        if (jscodechildlogic.innerText.trim() === '') {
          jscodechildlogic.innerHTML = html
        } else {
          jscodechildlogic.insertAdjacentHTML('beforeEnd', html)
        }
      }
    },
    createFromVariable(item) {
      if (
        this.relationfield.indexOf('.') >= 0 &&
        item.value.indexOf('.') >= 0
      ) {
        const gridlistname = this.relationfield.split('.')[0]
        if (gridlistname === item.value.split('.')[0]) {
          this.pasteHtmlAtCaret(
            `<span class="variable" val="${item.value}" vartype="1" contenteditable="false" isedit="1"  variabletype="0" >【${item.title}<span class="is-green" >变量</span>】</span>&nbsp;`
          )
        } else {
          this.pasteHtmlAtCaret(
            `<span class="variable" val="${item.value}" vartype="1" contenteditable="false" isedit="0" variabletype="1">【${item.title}<span class="is-fixed" >数组</span>】</span>&nbsp;`
          )
        }
      } else if (item.value.indexOf('.') >= 0) {
        this.pasteHtmlAtCaret(
          `<span class="variable" val="${item.value}" vartype="1" contenteditable="false" isedit="0" variabletype="1">【${item.title}<span class="is-fixed" >数组</span>】</span>&nbsp;`
        )
      } else {
        this.pasteHtmlAtCaret(
          `<span class="variable" val="${item.value}" vartype="1" contenteditable="false" isedit="0" variabletype="0">【${item.title}<span class="is-fixed" >变量</span>】</span>&nbsp;`
        )
      }
    },
    createCurrentVariable(item) {
      this.pasteHtmlAtCaret(
        `<span class="variable" val="${item.value}" vartype="2" contenteditable="false" isedit="0" variabletype="0">【${item.lable}<span class="is-read" >只读</span>】</span>&nbsp;`
      )
    },
    createfun(item) {
      this.pasteHtmlAtCaret(item + '()')
    },
    logicblur() {
      const docElement =
        window.event.srcElement.parentNode.className === 'variable'
          ? window.event.srcElement.parentNode
          : window.event.srcElement
      if (docElement.className === 'variable') {
        docElement.attributes.variabletype.value =
          docElement.attributes.variabletype.value === '0' ? '1' : '0'
        docElement.querySelectorAll('.is-green')[0].innerText =
          docElement.attributes.variabletype.value === '1' ? '数组' : '变量'
      }
      this.selection = window.getSelection()
    },
    dialogsave() {
      if (this.relationfield === '') {
        this.$message.error('请选择触发的方法！')
        return
      } else if (this.$refs.childlogic.innerHTML.trim() === '') {
        this.$message.error('逻辑代码不能为空！')
        return
      }
      let childlogicjscode = ''
      try {
        const variablelist = document.querySelectorAll('[val]')
        childlogicjscode = this.$refs.childlogic.innerHTML
        variablelist.forEach(ee => {
          const vartype = ee.attributes.vartype.value
          const attrfileds = ee.attributes.val.value
          if (vartype === '1') {
            if (attrfileds.indexOf('.') > 0) {
              const filedArry = attrfileds.split('.')
              if (this.relationfield.indexOf('.') > 0) {
                if (filedArry[0] === this.relationfield.split('.')[0]) {
                  childlogicjscode = childlogicjscode.replaceAll(
                    ee.outerHTML,
                    `datarow.${filedArry[1]}`
                  )
                }
              }
              childlogicjscode = childlogicjscode.replaceAll(
                ee.outerHTML,
                `"${filedArry[0]}","${filedArry[1]}"`
              )
            } else {
              childlogicjscode = childlogicjscode.replaceAll(
                ee.outerHTML,
                `${attrfileds}`
              )
            }
          } else {
            childlogicjscode = childlogicjscode.replaceAll(
              ee.outerHTML,
              `${attrfileds}`
            )
          }
        })
        childlogicjscode = childlogicjscode
          .replace(/<\/?.+?>/g, '')
          .replaceAll('；', ';')
          .replaceAll('，', '，')
          .replaceAll('“', '"')
          // .replaceAll('’', "\\'")
          .replaceAll('&nbsp;', '')
          .replaceAll('&amp;', '&')
        eval('function bb(){' + childlogicjscode + '}')
      } catch (ex) {
        this.$message.error('逻辑代码语法有问题！请检查！' + childlogicjscode)
        return
      }
      this.eventlist.forEach(ee => {
        if (ee.value === this.relationfield) {
          this.logicname = ee.title
        }
      })
      if (this.logicItem === undefined) {
        const key =
          Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
        const item = {
          logicname: this.logicname,
          relationfield: this.relationfield,
          jscode: this.$refs.childlogic.innerHTML.trim(),
          logickey: 'logic' + key
        }
        this.addlogic(item)
      } else {
        this.logicItem.logicname = this.logicname
        this.logicItem.relationfield = this.relationfield
        this.logicItem.jscode = this.$refs.childlogic.innerHTML.trim()
      }
      this.$emit('close')
    },
    dialogclose() {
      this.$emit('close')
    },
    createFunVariable(item) {
      this.pasteHtmlAtCaret(item)
    },
    clickFunVariable(context) {
      this.explaincontext = context
    },
    relationfieldchange() {
      if (document.getElementById('jscodechildlogic').innerText.trim() !== '') {
        this.$confirm(
          '切换事件后可能导致逻辑语法错误！是否清除逻辑语法！'
        ).then(() => {
          document.getElementById('jscodechildlogic').innerHTML = ''
        })
      }
    }
  },
  created() {
    this.fromVariableList = findAllFromVariable(this.fromInfo)
    this.eventlist = this.eventlist.concat(this.fromVariableList)
    this.fromInfo.logicList.forEach(ee => {
      if (
        !(
          this.logicItem !== undefined &&
          ee.relationfield === this.logicItem.relationfield
        )
      ) {
        for (let i = 0; i < this.eventlist.length; i++) {
          if (ee.relationfield === this.eventlist[i].value) {
            this.eventlist.splice(i, 1)
            break
          }
        }
      }
    })
    if (this.logicItem !== undefined) {
      this.logicname = this.logicItem.logicname
      this.relationfield = this.logicItem.relationfield
      this.jscode = this.logicItem.jscode
      this.isedit = true
    }
    this.$nextTick(() => {
      this.$refs.childlogic.focus()
    })
  },
  watch: {
    SetChangeFromInfo(val) {
      this.fromInfo = val
    }
  },
  inject: ['changeFromInfo', 'addlogic']
}
</script>
<style scoped>
.formplane {
  height: 600px;
  margin: 8px;
}
.fromitem {
  width: 100%;
  margin-top: 5px;
  display: inline-block;
}
.field-label {
  font-size: 12px;
  color: #91a1b7;
  line-height: 18px;
  margin-bottom: 5px;
  margin-left: 8px;
  display: inline-block;
  float: left;
}
.field-input {
  width: calc(100% - 120px);
  float: left;
}
.field-where {
  border: 1px solid #e0e0e0;
  width: 98%;
  height: 80px;
  margin: 8px;
  overflow: auto;
}
.field-where >>> .el-checkbox {
  background-color: #ecf5ff;
  display: inline-block;
  height: 32px;
  padding: 0 10px;
  line-height: 30px;
  font-size: 12px;
  color: #409eff;
  border: 1px solid #d9ecff;
  border-radius: 4px;
  box-sizing: border-box;
  white-space: nowrap;
  margin: 5px;
}
.field-where >>> .fieldcolor {
  background-color: #f0f9eb;
  border-color: #e1f3d8;
  color: #67c23a !important;
}
.field-where >>> .fieldcolor .el-checkbox__label {
  background-color: #f0f9eb;
  border-color: #e1f3d8;
  color: #67c23a !important;
}
.field-logic {
  border: 1px solid #e0e0e0;
  width: 98%;
  height: 150px;
  margin: 8px;
  overflow: auto;
  font-family: Consolas, 'Courier New', monospace;
  line-height: 20px;
  white-space: pre;
}

.field-logic >>> .variable {
  background-color: antiquewhite;
  display: inline-block;
}
.field-logic >>> .is-fixed,
.explain >>> .is-fixed {
  background-color: #f05050;
  border-radius: 10px;
  color: #fff;
  display: inline-block;
  font-size: 12px;
  height: 18 px;
  line-height: 18px;
  padding: 0 6px;
  text-align: center;
  white-space: nowrap;
  border: 1px solid #fff;
}
.field-logic >>> .is-read,
.explain >>> .is-read {
  background-color: #58585562;
  border-radius: 10px;
  color: #fff;
  display: inline-block;
  font-size: 12px;
  height: 18 px;
  line-height: 18px;
  padding: 0 6px;
  text-align: center;
  white-space: nowrap;
  border: 1px solid #fff;
}
.field-logic >>> .is-green,
.explain >>> .is-green {
  background-color: #05f786;
  border-radius: 10px;
  color: black;
  display: inline-block;
  font-size: 12px;
  height: 18 px;
  line-height: 18px;
  padding: 0 6px;
  text-align: center;
  white-space: nowrap;
  border: 1px solid #fff;
  cursor: pointer;
}
.fielditem1 {
  width: 40%;
  float: left;
}
.fielditem2 {
  width: 35%;
  float: left;
}
.fielditem3 {
  width: 25%;
  float: left;
}
.field-context {
  border: 1px solid #e0e0e0;
  width: 98%;
  height: 250px;
  margin: 8px;
  overflow: auto;
}
.field-context >>> .el-collapse-item__header {
  height: 32px !important;
  line-height: 32px !important;
  padding-left: 8px;
}
.fromfield {
  background-color: #ecf5ff;
  height: 32px;
  padding: 0 10px;
  line-height: 30px;
  font-size: 12px;
  color: #409eff;
  border: 1px solid #d9ecff;
  border-radius: 4px;
  box-sizing: border-box;
  white-space: nowrap;
  margin: 5px;
}
.fromfield:hover {
  background-color: #b4d5fc;
}
.buttonitem {
  float: right;
}
.eventclass {
  background-color: #409eff;
  display: inline-block;
  width: 12px;
  height: 12px;
}
.fieldclass {
  background-color: #67c23a;
  display: inline-block;
  width: 12px;
  height: 12px;
}
.explain {
  width: 100%;
  float: left;
  color: #91a1b7;
  line-height: 18px;
  font-size: 12px;
  margin-bottom: 5px;
  margin-left: 8px;
}
</style>
